//
//  FlutterBleImpl.swift
//  Runner
//
//  Created by 莫华军 on 2024/9/21.
//

import Foundation
import Flutter

//ble逻辑
class FlutterBleImpl:FlutterAppDelegate, JLBleMangerDelegate{
    
    
    func invokeMethod(methodName:String,arg:Any?){
        methodChannel?.invokeMethod(methodName, arguments: arg)
    }
    func invokeMethod(methodName:String){
        invokeMethod(methodName: methodName,  arg: "")
    }
    
    func onStartScan() {
        invokeMethod(methodName: "onStartScan")
    }
    
    func onStopScan() {
        invokeMethod(methodName: "onStopScan")
    }
    
    func onScanResult(_ name: String, identifier: String, byteData: Data ,rssi: NSNumber) {
        let byteArray = [UInt8](byteData)
        
        // 定义一个字典
        let dict: [String: Any] = [
            "name": name,
            "address": identifier,
            "bytes": byteArray,
            "rssi": rssi,
        ]
        invokeMethod(methodName: "onScanResult", arg: dict)
    }
    
    func onConnected(_ address: String) {
        invokeMethod(methodName: "onConnectSuccess",  arg: address)
    }
    
    func onDisconnected(_ address: String) {
        invokeMethod(methodName: "onDisConnect",  arg: address)
    }
    
    func onMtu(_ address: String, mtu: UInt) {
        let dict: [String: Any] = [
            "address": address,
            "mtu": mtu
        ]
        invokeMethod(methodName: "onMtuChanged",  arg: dict)
    }
    
    func onData(_ address: String, uuid: String, data: Data) {
        let dict: [String: Any] = [
            "address": address,
            "uuid":uuid,
            "data": data
        ]
        invokeMethod(methodName: "onData",  arg: dict)
    }
    
    static let sharedInstance = FlutterBleImpl()
    private var methodChannel: FlutterMethodChannel?
    private var bleManger = JLBleManager.sharedInstance()
    private override init() {
        
    }
    
    func initBle(){
        bleManger = JLBleManager.sharedInstance()
        bleManger.delegate = self
    }
    
    func setFlutterBinaryMessenger(binaryMessenger:FlutterBinaryMessenger){
        bleManger.delegate = self
        methodChannel = FlutterMethodChannel(name: bleManger.getMethodChannelName(), binaryMessenger: binaryMessenger)
        methodChannel?.setMethodCallHandler { (call:FlutterMethodCall, result:@escaping FlutterResult) in
            
            if (call.method == "startScan") {
                if let args = call.arguments as? [String: Any]{
                    let timeout = args["timeout"] as? Int
                    let int32Value: Int32 = Int32(timeout!)
                    print("扫描时间 \(int32Value)")
                    self.bleManger.startScanBLE(int32Value)
                }
                
            }else if(call.method == "stopScan"){
                self.bleManger.stopScanBLE();
            }else if(call.method == "connect"){
                let arg:String = call.arguments as! String
            
                self.invokeMethod(methodName: "onConnecting",  arg: arg)
                self.bleManger.connect(forMac: arg)
            }else if(call.method == "disconnect"){
                let arg:String = call.arguments as! String
                self.bleManger.disconnect(arg)
            }else if(call.method == "setCharacteristicNotification"){
                if let args = call.arguments as? [String: Any]{
                    let address = args["address"] as? String
                    let serverUUID = args["serviceUuid"] as? String
                    let characteristicUUID = args["uuid"] as? String
                    //let enable = args["enable"] as? Bool
                    self.bleManger.setCharacteristicNotification(address!, serviceUUID: serverUUID!, characteristicUUID: characteristicUUID!)
                }
            }else if(call.method == "write"){
                if let args = call.arguments as? [String: Any]{
                    let address = args["address"] as? String
                    let serverUUID = args["serviceUuid"] as? String
                    let characteristicUUID = args["uuid"] as? String
                    let stringData = args["data"] as? String
                    if let data = Data(base64Encoded: stringData!) {
                        self.bleManger.write(address!, serviceUUID: serverUUID!, characteristicUUID: characteristicUUID!, data: data)
                    }
                }
            }else if(call.method == "isGpsEnable"){
                result(["isGpsEnable":true])
            }else if(call.method == "isBleEnable"){
                result(["isBleEnable":self.bleManger.isBleOpen()])
            }else if(call.method == "openAuthorized"){
                //跳到授权界面
                if let url = URL(string: UIApplication.openSettingsURLString) {
                    UIApplication.shared.open(url, options: [:], completionHandler: nil)
                }
            }else if(call.method == "isAuthorized"){
                result(["isAuthorized":self.bleManger.isAuthorized()])
            }else if(call.method == "startOta"){
                //开始固件升级
                if let args = call.arguments as? [String: Any]{
                    //let address = args["address"] as? String
                    
                    let stringData = args["data"] as? String
                    if let data = Data(base64Encoded: stringData!) {
                        //print("升级数据:\(data)")
                        self.bleManger.otaFunc(withFilePath: data)
                    }
                }
            }else if(call.method == "setUUIDInfo"){
                //print("设置uuid信息 \(call.arguments)")
                ///设置uuid信息
                if let args = call.arguments as? [String: String]{
                    //print("设置uuid信息")
                    self.bleManger.setUUIDInfo(args)
                }
            }else if(call.method == "isOTA"){
                //是否是正在升级
                result(self.bleManger.isOTA())
            }else if(call.method == "getPlatformVersion"){
                result("iOS " + UIDevice.current.systemVersion)
            }
        }
    }
    
    
    
    //------------------------------------------------ota相关-------------------------------
    func onOtaStart() {
        invokeMethod(methodName: "onOtaStart")
    }
    
    func onOtaSuccess() {
        invokeMethod(methodName: "onOtaSuccess")
    }
    
    func onOtaFail(_ msg: UInt8) {
        invokeMethod(methodName: "onOtaFail",arg: msg)
    }
    
    func onOtaBootLoaderProgress(_ progress: Float) {
        invokeMethod(methodName: "onOtaBootLoaderProgress",  arg: Int(progress*100))
    }
    
    func onOtaProgress(_ progress: Float) {
        invokeMethod(methodName: "onOtaProgress",  arg: Int(progress*100))
    }
    
    func onMandatoryUpgrade(_ address: String) {
        invokeMethod(methodName: "onMandatoryUpgrade",  arg: address)
    }
    
    func onOtaAvailable(_ address: String, mac: String, mandatoryUpgrade isMandatoryUpgrade: Bool) {
        let dict: [String: Any] = [
            "address": address,
            "mac":mac,
            "isMandatoryUpgrade": isMandatoryUpgrade
        ]
        invokeMethod(methodName: "onOtaAvailable",  arg: dict)
    }
}
